package com.qingcloud.df.executor.process.docker;

import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Joiner;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.qingcloud.base.exception.WamingException;
import com.qingcloud.df.executor.pojo.process.config.AllowedHosts;
import com.qingcloud.df.executor.pojo.process.config.ResourceRequirements;
import com.qingcloud.df.executor.process.ProcessFactory;
import com.qingcloud.df.sdk.component.context.ConfigManager;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.nio.file.*;
import java.util.*;


/**
 *
 */

public class DockerProcessFactory implements ProcessFactory {
    private static final Logger logger = LoggerFactory.getLogger(DockerProcessFactory.class);
    private final String networkName;
    public DockerProcessFactory(

                                final String networkName) {
        this.networkName = networkName;
    }

    @Override
    public Process bulidProcess(String imageName,
                                String suffix,
                                String rootPath,
                                String componentNameEn,
                                Map<String, String> files,
                                String entrypoint,
                                ResourceRequirements resourceRequirements,
                                AllowedHosts allowedHosts,
                                String... args) {
        try {
            Path workspaceRoot = Path.of(rootPath);

            if(files != null && files.size()>0) {
                for (final Map.Entry<String, String> file : files.entrySet()) {
                    FileUtils.writeStringToFile(workspaceRoot.resolve(file.getKey()).toFile(), file.getValue());
                }
            }
            final List<String> cmd = Lists.newArrayList(
                    "docker",
                    "run",
                    "--rm",
                    "--init",
                    "-i");

            final String containerName = ProcessFactory.createProcessName(imageName, suffix, DOCKER_NAME_LEN_LIMIT);
            logger.info("Creating docker container = {} with resources {} and allowedHosts {}", containerName, resourceRequirements, allowedHosts);
            cmd.add("--name");
            cmd.add(containerName);

            if (networkName != null) {
                cmd.add("--network");
                cmd.add(networkName);
            }
            //组件执行日志挂载目录  组件内部配置信息
            cmd.add("-v");
            cmd.add(String.format("%s:%s", rootPath+ File.separator+ "logs", "/app/service/"+componentNameEn+"/logs"));
            cmd.add("-v");
            cmd.add(String.format("%s:%s", rootPath+ File.separator+ "config", "/app/service/"+componentNameEn+"/config"));


            //找配置文件中的TCP PORT
            JSONObject jsonObject = ConfigManager.loadParameterValueConfig(rootPath);
            Integer port  = 0;
            if(jsonObject!=null){
                for (Map.Entry<String, Object> entry : jsonObject.entrySet()) {
                    if(entry.getKey().equals("tcp.port")){
                        port=Integer.parseInt((String)entry.getValue());
                        break;
                    }
                }
            }
            if(port != 0){
                cmd.add("-p");
                cmd.add(port+":"+port);
            }

            if (!Strings.isNullOrEmpty(entrypoint)) {
                cmd.add("--entrypoint");
                cmd.add(entrypoint);
            }
            if (resourceRequirements != null) {
                if (!Strings.isNullOrEmpty(resourceRequirements.getCpuLimit())) {
                    cmd.add(String.format("--cpus=%s", resourceRequirements.getCpuLimit()));
                }
                if (!Strings.isNullOrEmpty(resourceRequirements.getMemoryRequest())) {
                    cmd.add(String.format("--memory-reservation=%s", resourceRequirements.getMemoryRequest()));
                }
                if (!Strings.isNullOrEmpty(resourceRequirements.getMemoryLimit())) {
                    cmd.add(String.format("--memory=%s", resourceRequirements.getMemoryLimit()));
                }
            }

            cmd.add(imageName);
            cmd.addAll(Arrays.asList(args));

            logger.info("Preparing command: {}", Joiner.on(" ").join(cmd));

            return new ProcessBuilder(cmd).start();
        } catch (final IOException e) {
            throw new WamingException(9000,e.getMessage());
        }
    }

    @Override
    public void processStop(String imageName ,String suffix) {
        final List<String> cmd = Lists.newArrayList("docker","stop");
        try {
            final String containerName = ProcessFactory.createProcessName(imageName, suffix, 128);
            cmd.add(containerName);
            logger.info("Preparing command: {}", Joiner.on(" ").join(cmd));
            new ProcessBuilder(cmd).start();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
//
//    boolean checkImageExists(final String imageName) {
//
//        try {
//            final Process process = new ProcessBuilder(imageExistsScriptPath.toString(), imageName).start();
//            if (process.isAlive()) {
//                throw new RuntimeException("该容器已经存在-"+imageName);
//            } else {
//                return process.exitValue() == 0;
//            }
//        } catch (final IOException e) {
//            throw new RuntimeException(e);
//        }
//    }
//
//
//    boolean checkContainerExists(final String containerName) {
//        try {
//            final Process process = new ProcessBuilder(imageExistsScriptPath.toString(), containerName).start();
//            if (process.isAlive()) {
//                throw new RuntimeException("该容器已经存在-"+containerName);
//            } else {
//                return process.exitValue() == 0;
//            }
//        } catch (final IOException e) {
//            throw new RuntimeException(e);
//        }
//    }
}
